package link_list

import "fmt"

type LinkList[T any] struct {
	Head         *LinkListNode[T]
	Tail         *LinkListNode[T]
	DefaultValue T
}

type LinkListNode[T any] struct {
	Next  *LinkListNode[T]
	Value T
}

func (l *LinkList[T]) Push(value T) {
	node := &LinkListNode[T]{}
	node.Value = value
	if l.Head == nil {
		l.Head = node
		l.Tail = node
	} else {
		l.Tail.Next = node
		l.Tail = node
	}
}

func (l *LinkList[T]) Pop() T {
	if l.Head == nil {
		return l.DefaultValue
	}
	value := l.Head.Value
	l.Head = l.Head.Next
	if l.Head == nil {
		l.Tail = nil
	}
	return value
}

func (l *LinkList[T]) String() string {
	if l.Head == nil {
		return "Empty"
	}
	var result = "[Start] -> "
	node := l.Head
	for {
		result += fmt.Sprintf("%v -> ", node.Value)
		node = node.Next
		if node == nil {
			return result + "[End]"
		}
	}
}
